#include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <map>
#include <cmath>
#include "calculator.h"
using namespace std;

vector<string> suffix; //存放后缀表达式
map<char, int> priority; //定义计算的优先级
string operators = "+-*/^()";    // 保存所有的计算符号

void trans(string str) //中缀转后缀
{
    stack<char> ops; //存放运算符的栈
    ops.push('#'); //标记栈底
    string tempStr;
    for (int i = 0; i < str.size(); i++)
    {   // 以下两种情况是带符号的数字
        // 1. 带正负号且前一个字符为运算符（i=0时直接带正负号的也是数字）
        // 2. 当前字符为数字
        if( ((str[i] == '-' || str[i] == '+') && (i == 0 || string("+-/*^(").find(str[i-1])!=string::npos)) || isdigit(str[i]) ) 
        {   // 把操作数加入到后缀式中
            // 如果是正号就不用加入，负号或者数字本身都要加入
            tempStr = str[i] != '+' ? str.substr(i, 1) : "";
            while (i + 1 < str.size() && operators.find(str[i+1]) == string::npos)
            {   // 可以把小数点也连接到数上，因此该计算器对小数也适用
                tempStr += str[++i];
                
            }
            suffix.push_back(tempStr);
        }
        else
        { // 出现操作符
            if(str[i] == '(')  //左括号直接入栈
                ops.push(str[i]); 
            else if(str[i] == ')') 
            {
                //如果遇到右括号，直接从操作符栈中弹出到后缀表达式中，直到遇到左括号
                while (ops.top() != '(')
                {
                    suffix.push_back(string(1, ops.top()));
                    ops.pop();
                }
                ops.pop();
            }
            else
            {
                //如果操作符优先级小于等于栈顶，就将操作符栈的操作符不断弹出到后缀表达式中，直到 op 的优先级高于栈顶操作符
                while (priority[str[i]] <= priority[ops.top()])
                {
                    suffix.push_back(string(1, ops.top()));
                    ops.pop();
                }
                ops.push(str[i]);
            }
        }
    }
    while (ops.size() > 1)
    {   //中缀表达式扫描完毕后，如果操作符栈中仍然有元素，则依次弹出放到后缀表达式中
        suffix.push_back(string(1, ops.top()));
        ops.pop();
    }
}



int main()
{
    priority['^'] = 4;
    priority['*'] = priority['/'] = 3;
    priority['+'] = priority['-'] = 2;
    priority['('] = 1;
    priority['#'] = 0;
    string str;
    getline(cin, str);
    int index = 0;
	if(!str.empty())
	{
		while( (index = str.find(' ',index)) != string::npos)
		{
			str.erase(index,1);
		}
	}
    if (check(str)==true)
    {
        trans(str);
        for (int i = 0; i < suffix.size(); i++)
        cout <<(i ? " " : "")<< suffix[i]; 
        double result = calculate(suffix);
        cout<< result<<endl;
    }
    return 0;
}
